﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
using Tnelab.Common;

namespace Tnelab.WebApp
{
    public enum StartPosition { Manual = 1, CenterScreen = 2, CenterParent = 3 }
    public enum WindowState { Maximized = 1, Normal = 2, Minimized = 3 }
    [ScriptCode(@"    
    StartPosition=({Manual:1, CenterScreen:2, CenterParent:3});    
    WindowState=({ Maximized:1, Normal:2, Minimized:3 });
    WebBrowserType=({Edge:1,MBVip:2,MBWke:3});
    ")]
    internal class WebWindow : IWebWindow
    {
        const uint WM_UIInvoke = 0x400 + 0x100;
        static readonly Dictionary<IntPtr, WebWindow> _WebWindows = new Dictionary<IntPtr, WebWindow>();
        static readonly IntPtr _AppInstance;
        static readonly string _WindowClassName;


        string _url;
        bool _isDesdroyed = false;
        WindowState _windowState = WindowState.Normal;
        string? _icon;
        string _title = "MainWindow";
        int _x = 0;
        int _y = 0;
        int _width = 1024;
        int _height = 768;
        bool _showInTaskBar = true;
        bool _topMost = false;
        bool _isBorderRect = false;
        bool _SizeAble = true;

        public event EventHandler<bool> SizeAbleChanged;
        public event EventHandler<WindowState> WindowStateChanged;
        [DoNotConvertToScript]
        public IWebBrowser WebBrowser { get; private set; }
        public WebBrowserType BrowserType { get => this.WebBrowser.BrowserType; }
        public string Name { get; private set; }
        public IntPtr Handle { get; protected set; }
        [ScriptCode(@"
            get Parent(){
                return new Promise((resolve, reject) => {
                    if(""{Context.Parent.Name}""==="""") resolve(null);
                    resolve(eavl(""{Context.Parent.Name}""));
                });                
            }
        ")]
        public IWebWindow? Parent {
            get; 
            protected set; 
        }
        public string Url
        {
            get => _url;
            set
            {
                if (string.IsNullOrEmpty(value.Trim())) {
                    throw new ArgumentException("Url不能为空");
                }
                _url = value;
                if (this.WebBrowser != null)
                {
                    this.WebBrowser.LoadUrl(Url);
                }
            }
        }
        public WindowState WindowState
        {
            get => _windowState;
            set
            {
                if (this._isDesdroyed)
                    throw new Exception("窗口已经被释放");
                if (this.Handle != IntPtr.Zero)
                {
                    switch (value)
                    {
                        case WindowState.Maximized:
                            Win32Api.ShowWindow(this.Handle, Win32Api.SW_MAXIMIZE);
                            break;
                        case WindowState.Normal:
                            Win32Api.ShowWindow(this.Handle, Win32Api.SW_NORMAL);
                            break;
                        case WindowState.Minimized:
                            Win32Api.ShowWindow(this.Handle, Win32Api.SW_MINIMIZE);
                            break;
                    }
                }
                this._windowState = value;
                this.OnWindowStaeChanged(this, value);
            }
        }
        public string? Icon
        {
            get
            {
                return _icon;
            }
            set
            {
                _icon = value;
                if (this.Handle != IntPtr.Zero && _icon != null)
                {                    
                    using (var stream = WebApplication.GetManifestResource(value))
                    {
                        if (stream == null)
                        {
                            _icon = null;
                            return;
                        }
                        var datas = new byte[stream.Length];
                        stream.Read(datas, 0, datas.Length);
                        File.WriteAllBytes("d:\\test.ico", datas);

                        var ptr = Marshal.AllocHGlobal((int)stream.Length);
                        Marshal.Copy(datas, 0, ptr, datas.Length);
                        //var hIcon = Win32Api.CreateIconFromResourceEx(ptr, datas.Length, true, 0x30000, 32, 32, Win32Api.LR_DEFAULTCOLOR);
                        var hIcon = Win32Api.CreateIconFromResource(ptr, datas.Length, true, 0x30000);
                        Win32Api.PostMessage(this.Handle, Win32Api.WM_SETICON, new IntPtr(Win32Api.ICON_BIG), new IntPtr((uint)hIcon));
                        Win32Api.PostMessage(this.Handle, Win32Api.WM_SETICON, new IntPtr(Win32Api.ICON_SMALL), new IntPtr((uint)hIcon));
                        Marshal.FreeHGlobal(ptr);
                    }
                }
            }
        }
        public string Title
        {
            get
            {
                return _title;
            }
            [DoNotConvertToScript]
            set
            {        
                _title = value;
                if (this.Handle != IntPtr.Zero)
                {
                    Win32Api.SetWindowTextW(this.Handle, _title);
                }
            }
        }
        [ScriptCode(@"
            _sizeAble=true;
            get SizeAble(){  
                return new Promise((resolve, reject) => {
                    resolve(this._sizeAble);
                });
            }
            set SizeAble(val){
                this._sizeAble=val;
                this._SizeAble=val;
            }
        ")]
        public bool SizeAble { 
            get => _SizeAble; 
            set 
            { 
                this._SizeAble = value;
                this.OnSizeAbleChanged(this, value);
            } 
        }
        public int X
        {
            get
            {
                if (this.Handle != IntPtr.Zero)
                    _x = GetWindowRect().left;
                return _x;
            }
            set
            {
                if (this.Handle != IntPtr.Zero)
                {
                    var rect = GetWindowRect();
                    Win32Api.MoveWindow(this.Handle, value, rect.top, rect.right - rect.left, rect.bottom - rect.top, true);
                }
                _x = value;
            }
        }
        public int Y
        {
            get
            {
                if (this.Handle != IntPtr.Zero)
                    _y = GetWindowRect().top;
                return _y;
            }
            set
            {
                if (this.Handle != IntPtr.Zero)
                {
                    var rect = GetWindowRect();
                    Win32Api.MoveWindow(this.Handle, rect.left, value, rect.right - rect.left, rect.bottom - rect.top, true);
                }
                _y = value;
            }
        }
        public int Width
        {
            get
            {
                if (this.Handle != IntPtr.Zero)
                {
                    var rect = GetWindowRect();
                    _width = rect.right - rect.left;
                }
                return _width;
            }
            set
            {
                if (this.Handle != IntPtr.Zero)
                {
                    var rect = GetWindowRect();
                    Win32Api.MoveWindow(this.Handle, rect.left, rect.top, value, rect.bottom - rect.top, true);
                }
                _width = value;
            }
        }
        public int Height
        {
            get
            {
                if (this.Handle != IntPtr.Zero)
                {
                    var rect = GetWindowRect();
                    _height = rect.bottom - rect.top;
                }
                return _height;
            }
            set
            {
                if (this.Handle != IntPtr.Zero)
                {
                    var rect = GetWindowRect();
                    Win32Api.MoveWindow(this.Handle, rect.left, rect.top, rect.right - rect.left, value, true);
                }
                _height = value;
            }
        }
        public int MinWidth { get; set; } = 0;
        public int MinHeight { get; set; } = 0;
        public bool ShowInTaskBar
        {
            get
            {
                return _showInTaskBar;
            }
            set
            {
                _showInTaskBar = value;
                if (this.Handle != IntPtr.Zero)
                {
                    int old = Win32Api.GetWindowLong(this.Handle, Win32Api.GWL_EXSTYLE);
                    if (value)
                    {
                        Win32Api.SetWindowLong(this.Handle, Win32Api.GWL_EXSTYLE, old & ~Win32Api.WS_EX_TOOLWINDOW);
                    }
                    else
                    {
                        Win32Api.SetWindowLong(this.Handle, Win32Api.GWL_EXSTYLE, old | Win32Api.WS_EX_TOOLWINDOW);
                    }
                }

            }
        }
        public bool TopMost
        {
            get
            {
                return this._topMost;
            }
            set
            {
                this._topMost = value;
                if (this.Handle != IntPtr.Zero)
                {
                    if (this._topMost)
                    {
                        Win32Api.SetWindowPos(this.Handle, new IntPtr(-1), 0, 0, 0, 0, 0x0002 | 0x0001);
                    }
                    else
                    {
                        Win32Api.SetWindowPos(this.Handle, new IntPtr(-2), 0, 0, 0, 0, 0x0002 | 0x0001);
                    }
                }
            }
        }


        static WebWindow()
        {
            _AppInstance = System.Diagnostics.Process.GetCurrentProcess().Handle;
            _WindowClassName = $"Tnelab_WebApp_Window_{new Random(DateTime.Now.Millisecond).Next()}";
            RegisterWindowClass(_WindowClassName);
        }
        public WebWindow(WebWindow? parent, string name, IWebBrowser webBrowser, string url)
        {
            if (string.IsNullOrEmpty(name.Trim()))
                throw new ArgumentNullException(nameof(Name));
            if (webBrowser == null)
                throw new ArgumentNullException(nameof(webBrowser));
            if (string.IsNullOrEmpty(url.Trim()))
                throw new ArgumentNullException(nameof(url));
            this.Name = name;
            this.Parent = parent;
            WebBrowser = webBrowser;
            _url = url.Trim();
            this.WebBrowser.Paint += WebBrowser_Paint;
            this.WebBrowser.WebViewIsReady += WebBrowser_WebViewIsReady;
        }
        protected void OnSizeAbleChanged(object sender,bool value)
        {
            this.SizeAbleChanged?.Invoke(sender, value);
        }
        protected void OnWindowStaeChanged(object sender, WindowState state)
        {
            this.WindowStateChanged?.Invoke(sender,state);
        }
        public void UIInvoke(Action action)
        {
            if (action == null)
                throw new ArgumentNullException(nameof(action));
            if (this.Handle == IntPtr.Zero)
                throw new InvalidOperationException("Window Handle Is NULL.");
            var actionPtr = Marshal.GetFunctionPointerForDelegate(action);
            if (actionPtr == IntPtr.Zero)
                throw new Exception("UIInvoke GetFunctionPointerForDelegate Return NULL");
            Debug.WriteLine("UIInvoke");
            Win32Api.SendMessage(this.Handle, WM_UIInvoke, actionPtr, IntPtr.Zero);
        }

        private void WebBrowser_Paint(object? sender, PaintEventArg e)
        {
            var winHdc = Win32Api.GetDC(this.Handle);
            IntPtr bitHdc=IntPtr.Zero;
            if (e.Hdc != IntPtr.Zero)
            {
                bitHdc = e.Hdc;
            }
            else
            {
                bitHdc = Win32Api.CreateCompatibleDC(winHdc);

                Win32Api.SelectObject(bitHdc, e.Bitmap.GetHbitmap());
            }

            //Win32Api.BitBlt(winHdc, 0, 0, this.width_, this.height_, e.Hdc, 0, 0, Win32Api.SRCCOPY);
            //return;

            //var bitHdc=Win32Api.CreateCompatibleDC(winHdc);
            //var bitmap = e.Bitmap;
            //byte[] newData = new byte[this.Width * this.Height * 4];
            //for (var i = 0; i < this.Height * this.Width * 4; i += 4)
            //{
            //    newData[i + 2] = 255;
            //    newData[i + 3] = 120;
            //}
            //Win32Api.SelectObject(bitHdc, bitmap.GetHbitmap());

            var rect = new Win32Api.RECT();
            Win32Api.GetWindowRect(this.Handle, out rect);

            Win32Api.POINT point = new Win32Api.POINT();
            point.x = rect.left;
            point.y = rect.top;

            Win32Api.SIZE size = new Win32Api.SIZE();
            size.cx = rect.right - rect.left;
            size.cy = rect.bottom - rect.top;

            Win32Api.POINT point2 = new Win32Api.POINT();
            point2.x = 0;
            point2.y = 0;

            Win32Api.BLENDFUNCTION blInfo = new Win32Api.BLENDFUNCTION();
            blInfo.BlendOp = Win32Api.AC_SRC_OVER;
            blInfo.BlendFlags = 0;
            blInfo.AlphaFormat = Win32Api.AC_SRC_ALPHA;
            blInfo.SourceConstantAlpha = 0xFF;

            //var oldExStyle = Win32Api.GetWindowLong(this.Handle, Win32Api.GWL_EXSTYLE);
            //Win32Api.SetWindowLong(this.Handle, Win32Api.GWL_EXSTYLE, Win32Api.WS_EX_LAYERED);

            if (BrowserType == WebBrowserType.Edge)
            {
                Win32Api.BitBlt(winHdc, 0, 0, this.Width, this.Width, bitHdc, 0, 0, Win32Api.SRCCOPY);
            }
            else
            {
                Win32Api.UpdateLayeredWindow(this.Handle, winHdc, ref point, ref size, bitHdc, ref point2, 0, ref blInfo, Win32Api.ULW_ALPHA);
            }            
            Win32Api.ReleaseDC(this.Handle, winHdc);
        }

        private void WebBrowser_WebViewIsReady(object? sender, EventArgs e)
        {
            this.Url = this.Url;
            this.TopMost = this.TopMost;
            this.WebBrowser.TitleChanged += WebBrowser_TitleChanged;
        }

        private void WebBrowser_TitleChanged(object? sender, TitleChangedArgs e)
        {
            this.Title = e.Title;
        }

        static void RegisterWindowClass(string className)
        {
            Win32Api.WNDCLASS wcex = new Win32Api.WNDCLASS();
            wcex.style = Win32Api.CS_HREDRAW | Win32Api.CS_VREDRAW|Win32Api.CS_OWNDC;
            wcex.lpfnWndProc = Marshal.GetFunctionPointerForDelegate((Win32Api.WinProcDelegate)GWinProc);
            wcex.lpszClassName = className;
            wcex.hInstance = _AppInstance;
            wcex.hCursor = Win32Api.LoadCursorW(IntPtr.Zero, 32512);
            //wcex.hbrBackground = IntPtr.Zero;
            var result = Win32Api.RegisterClassW(ref wcex);
            if (result == IntPtr.Zero)
            {
                throw new Exception($"注册窗口类失败,错误代码:{Marshal.GetLastWin32Error()}");
            }
        }
        static int GWinProc(IntPtr hWnd, uint message, IntPtr wParam, IntPtr lParam)
        {
            if (_WebWindows.ContainsKey(hWnd))
            {
                return _WebWindows[hWnd].WinProc(hWnd, message, wParam, lParam);
            }
            return Win32Api.DefWindowProc(hWnd, message, wParam, lParam);
        }

        public void ShowDialog()
        {
            if (this.Handle == IntPtr.Zero)
            {
                CreateWindow();
            }
            this.WindowState = this.WindowState;
            if (this.Parent != null)
            {
                Win32Api.EnableWindow(Parent.Handle, false);
            }
        }
        public void Show()
        {
            if (this.Handle == IntPtr.Zero)
            {
                CreateWindow();
            }
            this.WindowState = this.WindowState;
            Win32Api.SetActiveWindow(this.Handle);
            //uint old = Win32Api.GetWindowLong(this.Handle, Win32Api.GWL_EXSTYLE);
            //Win32Api.SetWindowLong(this.Handle, Win32Api.GWL_EXSTYLE, old & ~Win32Api.WS_EX_LAYERED);
        }
        public void Hide()
        {
            if (this.Handle == IntPtr.Zero)
            {
                CreateWindow();
            }
            Win32Api.ShowWindow(this.Handle, Win32Api.SW_HIDE);
        }
        public void OnMove()
        {
            Win32Api.ReleaseCapture();
            Win32Api.SendMessage(this.Handle, Win32Api.WM_SYSCOMMAND, new IntPtr(Win32Api.SC_MOVE | Win32Api.HTCAPTION), IntPtr.Zero);
        }
        public void Close()
        {
            Win32Api.PostMessage(this.Handle, Win32Api.WM_CLOSE, IntPtr.Zero,IntPtr.Zero);
        }
        [ScriptCode(@"
        async NewWindow(name,url){
	        await this._NewWindow(name,url);
	        return eval(name);
        }
        ")]
        public async Task NewWindow(string name,string url)
        {
            url = url.ToLower();
            if(url.IndexOf("://") == -1){
                if (url[0] == '/')
                {
                    var uri = new Uri(this.Url);
                    if(uri.Scheme == "file")
                    {
                        url = $"file://{url}";
                    }
                    else
                    {
                        var portStr= uri.Port == 80 ? "":":" + uri.Port.ToString();
                        var aname=this.Url.Remove(0, $"{uri.Scheme}://{uri.Host}{portStr}".Length + 1).Split('/')[0];
                        url = $"{uri.Scheme}://{uri.Host}{portStr}/{aname}{url}";
                    }
                }
                else
                {
                    var inpath= this.Url.Substring(0, this.Url.LastIndexOf("/"));
                    url = $"{inpath}/{url}";
                }
            }
            try
            {
                await WebApplication.NewWindow(this, name, url);
            }
            catch (Exception ex)
            {
                throw new Exception($"NewWindow Exception:{ex.Message}.name:{name},url:{url}",ex);
            }
        }
        [ScriptCode(@"
        async CallJs(script){
            return await this._CallJs(script);
        }
        async FunctionToRun(func){
            let script=""(""+func.toString()+"")()"";
            return await this._CallJs(script);
        }
        ")]
        public async Task<string> CallJs(string script)
        {
            var result = await this.WebBrowser.CallJsAsync(script);
            return result;
        }
        public void SetPosition(StartPosition position)
        {
            if (position == StartPosition.CenterScreen || (position == StartPosition.CenterParent && this.Parent == null))
            {
                var scrWidth = Win32Api.GetSystemMetrics(Win32Api.SM_CXSCREEN);
                var scrHeight = Win32Api.GetSystemMetrics(Win32Api.SM_CYSCREEN);

                _x = (scrWidth - this.Width) / 2;
                _y = (scrHeight - this.Height) / 2;
            }
            else if (position == StartPosition.CenterParent)
            {
                _x = (Parent.Width - this.Width) / 2 + this.Parent.X;
                _y = (Parent.Height - this.Height) / 2 + this.Parent.Y;
            }
            var rect = GetWindowRect();
            Win32Api.MoveWindow(this.Handle, _x, _y, rect.right - rect.left, rect.bottom - rect.top, true);
        }
        public void OnChangeSize(int wmszValue)
        {
            Win32Api.ReleaseCapture();
            Win32Api.SendMessage(this.Handle, Win32Api.WM_SYSCOMMAND, new IntPtr(Win32Api.SC_SIZE | wmszValue), IntPtr.Zero);
        }
        protected virtual int WinProc(IntPtr hWnd, uint message, IntPtr wParam, IntPtr lParam)
        {
            int? result = null;
            if (message == Win32Api.WM_NCHITTEST && SizeAble)
            {
                result = GetBorderRect(lParam);
                _isBorderRect = result != 0;
                if (_isBorderRect)
                {
                    return result.Value;
                }
            }
            if (message == Win32Api.WM_SETCURSOR && _isBorderRect)
            {
                result = Win32Api.DefWindowProc(hWnd, message, wParam, lParam);
                _isBorderRect = false;
                return result.Value;
            }


            switch (message)
            {
                case WM_UIInvoke:
                    Debug.WriteLine("UIInvoke Message");

                    var action = Marshal.GetDelegateForFunctionPointer<Action>(wParam);
                    action();
                    result = 0;
                    break;
                case Win32Api.WM_CLOSE:
                    result = 0;
                    Win32Api.DestroyWindow(this.Handle);
                    break;
                case Win32Api.WM_DESTROY:
                    if (this.Parent != null)
                        Win32Api.EnableWindow(this.Parent.Handle, true);
                    WebBrowser.Dispose();
                    WebApplication.UIServices.Remove(this.Name);
                    WebWindow._WebWindows.Remove(this.Handle);
                    if (this.Handle == WebApplication.MainWindow?.Handle)
                    {
                        WebApplication.WebAppServer?.Stop();
                        Win32Api.PostQuitMessage(0);
                    }
                    result = 0;
                    break;
                case Win32Api.WM_GETMINMAXINFO:
                    WmGetMinMaxInfo(hWnd, lParam);
                    result = 0;
                    break;
                default:
                    result = this.WebBrowser.OnHostWindowMessageProc(hWnd, message, wParam, lParam);                   
                    break;
            }    
            if(result==null)
            {
                result = Win32Api.DefWindowProc(hWnd, message, wParam, lParam);
            }
            return result.Value;
        }
        protected virtual void CreateWindow()
        {
            var exStyle = Win32Api.WS_EX_APPWINDOW;

            if (!this._showInTaskBar)
                exStyle |= Win32Api.WS_EX_TOOLWINDOW;
            int style = Win32Api.WS_POPUP;

            var result = Win32Api.CreateWindowExW(exStyle, _WindowClassName, this.Title, style, this.X, this.Y, this.Width, this.Height, this.Parent==null?IntPtr.Zero:this.Parent.Handle, IntPtr.Zero, _AppInstance, IntPtr.Zero);
            if (result == IntPtr.Zero)
            {
                throw new Exception($"创建窗口失败,错误代码:{Marshal.GetLastWin32Error()}");
            }
            _WebWindows.Add(result, this);
            this.Handle = result;
            //Win32Api.UpdateWindow(this.Handle);
            this.SetPosition(StartPosition.CenterParent);
            this.WebBrowser.OnHostWindowCreated(this);            
        }
        Win32Api.RECT GetWindowRect()
        {
            var rect = new Win32Api.RECT();
            Win32Api.GetWindowRect(this.Handle, out rect);
            return rect;
        }
        int GetBorderRect(IntPtr lParam)
        {
            if (!Win32Api.IsZoomed(this.Handle))
            {
                var x = Win32Api.LOWORD(lParam);
                var y = Win32Api.HIWORD(lParam);
                Win32Api.RECT rect = new Win32Api.RECT();
                Win32Api.GetWindowRect(this.Handle, out rect);
                var borderWidth = 6;
                //窗口左上角
                if (x > rect.left && x < rect.left + borderWidth && y > rect.top && y < rect.top + borderWidth)
                {
                    return (int)Win32Api.HitTest.HTTOPLEFT;
                }
                //窗口左下角
                else if (x > rect.left && x < rect.left + borderWidth && y > rect.bottom - borderWidth && y < rect.bottom)
                {
                    return (int)Win32Api.HitTest.HTBOTTOMLEFT;
                }
                //窗口右上角
                else if (x > rect.right - borderWidth && x < rect.right && y > rect.top && y < rect.top + borderWidth)
                {
                    return (int)Win32Api.HitTest.HTTOPRIGHT;
                }
                //窗口右下角
                else if (x > rect.right - borderWidth && x < rect.right && y > rect.bottom - borderWidth && y < rect.bottom)
                {
                    return (int)Win32Api.HitTest.HTBOTTOMRIGHT;
                }
                //窗口左侧
                else if (x > rect.left && x < rect.left + borderWidth && y > rect.top + borderWidth && y < rect.bottom - borderWidth)
                {
                    return (int)Win32Api.HitTest.HTLEFT;
                }
                //窗口右侧
                else if (x > rect.right - borderWidth && x < rect.right && y > rect.top + borderWidth && y < rect.bottom - borderWidth)
                {
                    return (int)Win32Api.HitTest.HTRIGHT;
                }
                //窗口上侧
                else if (x > rect.left + borderWidth && x < rect.right - borderWidth && y > rect.top && y < rect.top + borderWidth)
                {
                    return (int)Win32Api.HitTest.HTTOP;
                }
                //窗口下侧
                else if (x > rect.left + borderWidth && x < rect.right - borderWidth && y > rect.bottom - borderWidth && y < rect.bottom)
                {
                    return (int)Win32Api.HitTest.HTBOTTOM;
                }
            }
            return 0;
        }
        void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
        {
            Win32Api.MINMAXINFO mmi = (Win32Api.MINMAXINFO)Marshal.PtrToStructure((IntPtr)lParam, typeof(Win32Api.MINMAXINFO));

            int MONITOR_DEFAULTTONEAREST = 0x00000002;
            IntPtr monitor = Win32Api.MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

            if (monitor != IntPtr.Zero)
            {
                Win32Api.MONITORINFO monitorInfo = new Win32Api.MONITORINFO();
                Win32Api.GetMonitorInfo(monitor, monitorInfo);
                Win32Api.RECT rcWorkArea = monitorInfo.rcWork;
                Win32Api.RECT rcMonitorArea = monitorInfo.rcMonitor;
                mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
                mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);
                mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
                mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
                mmi.ptMinTrackSize.x = this.MinWidth;
                mmi.ptMinTrackSize.y = this.MinHeight;
            }

            Marshal.StructureToPtr(mmi, (IntPtr)lParam, true);

        }
    }
}
